#define _CRT_SECURE_NO_WARNINGS
//#include "log.hpp"
//#include "UdpServer.hpp"
#include <iostream>
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <cstring>
#include <string>
//#include <strings.h>
//#include <pthread.h>
//#include <unistd.h>
#include <stdlib.h>
#include <thread>
#include <Windows.h>

#pragma comment(lib, "ws2_32.lib")

using namespace std;

enum
{
    SOCKET_ERR = 1,
    BIND_ERR,
};

struct ThreadDate
{
    sockaddr_in _server;
    SOCKET _sockfd;
    std::string _serverip;
};

//void Useag(char *argv)
//{
//    cout << "you should input like this:" << argv << " a.b.c.d(Ip)" << " xxxx(port)" << endl;
//}

void Received(ThreadDate* Td)
{
    char inbuffer[1024];

    while (1)
    {
        memset(inbuffer, 0, sizeof(inbuffer));

        struct sockaddr_in temp;
        socklen_t len=sizeof(temp);
        int s = recvfrom(Td->_sockfd,inbuffer,1023,0,(sockaddr*)&temp,&len);
        if(s>0)
        {
            inbuffer[s] = 0;
            char clientIP[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, &temp.sin_addr, clientIP, INET_ADDRSTRLEN);
            cout << "[" << clientIP << ":" << ntohs(temp.sin_port) << "]: " 
                << inbuffer << endl;
        }

    }
}

void Send(ThreadDate* Td)
{
    string messages;
    while (1)
    {

        cout << "Please Enter Message@ ";
        getline(cin, messages);

        int s = sendto(Td->_sockfd, messages.data(), messages.size(), 0,
            (sockaddr *)&(Td->_server), sizeof(Td->_server));
        if (s == -1)
        {
            cerr << "Waring: Sento Error " << endl;
            continue;
        }
        Sleep(200);
    }
}

int main()
{
    WSADATA wsaData;
    int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (result != 0) {
        return 1;
    }
    string ServerIp = "111.229.216.191";
    uint16_t ServerPort = stoi("8888");

    ThreadDate Td;
    memset(&Td._server, 0,sizeof(Td._server));
    Td._server.sin_family = AF_INET;
    Td._server.sin_port = htons(ServerPort);
    if (inet_pton(AF_INET, ServerIp.c_str(), &Td._server.sin_addr) != 1)
    {
        cerr << "Invalid IP address format" << endl;
        WSACleanup();
        return 1;
    }
    Td._serverip = ServerIp;

    Td._sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (Td._sockfd < 0)
    {
        cerr << "Socket creation failed: " << WSAGetLastError() << endl;
        WSACleanup();
        return 1;
    }

    u_long mode = 0; // 1为非阻塞，0为阻塞
    if (ioctlsocket(Td._sockfd, FIONBIO, &mode) != 0) 
    {
        cerr << "Set blocking mode failed: " << WSAGetLastError() << endl;
        closesocket(Td._sockfd);
        WSACleanup();
        return 1;
    }

    cout << "Connecting to server " << ServerIp << ":" << ServerPort << endl;

    std::thread recvr(Received, &Td);
    std::thread sender(Send, &Td);

    recvr.join();
    sender.join();

    closesocket(Td._sockfd);
    WSACleanup();
    return 0;
}